package com.ptswitch.material.service.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hxzon.project.AbstractModelService;
import org.springframework.stereotype.Service;

import com.ptswitch.material.model.common.Uzer;
import com.ptswitch.material.model.security.Role;
import com.ptswitch.material.model.security.RolePermission;
import com.ptswitch.material.model.security.UserRole;
import com.ptswitch.material.service.RoleService;
import com.ptswitch.material.util.security.RoleUtil;

@Service
public class RoleServiceImpl extends AbstractModelService<Role> implements RoleService {
    @Override
    public void initRoles() {
        long count = dao.countList(Role.class);
        if (count == 0) {
            dao.addAll(RoleUtil.roles);
        } else {
            addRelateRole();
        }
    }

    private void addRelateRole() {
        List<Role> dbRoles = findByRoleGroup(RoleUtil.RoleGroupName_Relate);
        Map<String, Role> dbRoleMap = new HashMap<String, Role>();
        for (Role dbRole : dbRoles) {
            dbRoleMap.put(dbRole.getRoleName(), dbRole);
        }
        for (Role r : RoleUtil.roles) {
            if (RoleUtil.RoleGroupName_Relate.equals(r.getRoleGroup())) {
                Role dbRole = dbRoleMap.get(r.getRoleName());
                if (dbRole == null) {
                    dao.add(r);
                } else {
                    r.setId(dbRole.getId());
                }
            }
        }
    }

    //
    @Override
    public List<Uzer> listUserByRoleInfo(long roleId, String username, boolean in, long first, long size) {
        String where = " where p.username like :username and ";
        if (!in) {
            where += " not ";
        }
        where += " exists (select 1 from p.userRoles ur where :roleId in ur.roleId)  order by p.username ";
        return dao.list(Uzer.class, where, first, size,// 
                "roleId", roleId, "username", ("%" + username + "%"));
    }

    @Override
    public long countUserByRoleInfo(long roleId, String username, boolean in) {
        String where = " where p.username like :username and ";
        if (!in) {
            where += " not ";
        }
        where += " exists (select 1 from p.userRoles ur where :roleId in ur.roleId) ";
        return dao.countList(Uzer.class, where,// 
                "roleId", roleId, "username", ("%" + username + "%"));
    }

    //
    @Override
    public List<Role> findRoles(Role... roles) {
        if (roles.length == 0) {
            return Collections.emptyList();
        }
        StringBuilder whereHql = new StringBuilder(" where p.roleName in (");
        for (Role role : roles) {
            whereHql.append("'").append(role.getRoleName()).append("'").append(",");
        }
        whereHql.append("''").append(")");
        return dao.list(Role.class, whereHql.toString(), -1, -1);
    }

    @Override
    public List<Role> findRoles(List<Role> roles) {
        return findRoles(roles.toArray(new Role[roles.size()]));
    }

    @Override
    public List<Role> findRoles(Collection<Long> roleIds) {
        if (roleIds.size() == 0) {
            return Collections.emptyList();
        }
        StringBuilder whereHql = new StringBuilder(" where p.roleId in (");
        for (Long roleId : roleIds) {
            whereHql.append(roleId).append(",");
        }
        whereHql.append("0").append(")");
        return dao.list(Role.class, whereHql.toString(), -1, -1);
    }

    @Override
    public List<Role> findByRoleGroup(String groupName) {
        return dao.listByProperty(Role.class, "roleGroup", groupName, -1, -1);
    }

    @Override
    public List<Role> findNormalRoles() {
        return dao.list(Role.class, " where p.roleGroup !='relate' ", -1, -1);
    }

    @Override
    public List<Role> findRelateRoles() {
        return dao.list(Role.class, " where p.roleGroup ='relate'", -1, -1);
    }

    @Override
    public void saveRolePermissions(List<RolePermission> rps) {
        dao.saveAll(rps);
    }

    @Override
    public void saveUserRoles(List<UserRole> urs) {
        dao.saveAll(urs);
    }
}
